from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth import authenticate, login as django_login, logout as django_logout, get_user_model
from .forms import UserRegistrationForm, UserLoginForm, DataUploadForm, ResaleForm, TokenForm, TokenVerificationForm
from django.http import HttpResponse, JsonResponse
from PIL import Image, ImageDraw, ImageFont
import random
import string
import io
from django.conf import settings
from django.contrib.auth.decorators import login_required
import uuid
from django.utils import timezone
import hashlib
import base64
import json
from .models import DataOwnership, AuthorizationToken, ResaleRecord
import os
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from .utils import generate_homomorphic_token, deserialize_encrypted_data, encrypt_token
from phe import paillier

# 获取用户模型，在文件顶部定义一次
User = get_user_model()


@login_required
@require_http_methods(["GET"])
def get_user_id(request):
    """
    获取当前登录用户的电话号码

    :param request: 请求对象
    :return: 返回包含用户电话号码的JSON响应
    """
    phone_number = request.user.phone_number
    return JsonResponse({'phoneNumber': phone_number})  # 改为返回 phoneNumber


@csrf_exempt
@require_http_methods(["POST"])
@login_required
def upload(request):
    """
    处理数据上传请求

    :param request: 请求对象
    :return: 返回数据上传成功的JSON响应
    """
    data_name = request.POST.get('dataName')
    data_description = request.POST.get('dataDescription')
    data_file = request.FILES.get('dataFile')
    hash_value = request.POST.get('hash')
    phone_number = request.POST.get('phoneNumber')

    # 生成同态加密令牌
    token_data = generate_homomorphic_token()

    data_ownership = DataOwnership(
        owner=request.user,
        data_file=data_file,
        signature=hash_value,
        token=token_data['token'],
        public_key=str(token_data['public_key']),
        private_key=str(token_data['private_key'])
    )
    data_ownership.save()

    return JsonResponse({'message': '数据上传成功'})


@csrf_exempt
def verify_signature(request):
    """
    验证签名

    :param request: 请求对象
    :return: 返回签名验证结果的JSON响应
    """
    token = request.GET.get('token')
    signature = request.GET.get('signature')

    try:
        # 只用token和signature查找
        data_obj = DataOwnership.objects.get(token=token, signature=signature)
        return JsonResponse({
            'success': True,
            'owner_phone': data_obj.owner.phone_number,
            'message': f'该数据属于用户（电话：{data_obj.owner.phone_number}）'
        })
    except DataOwnership.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '签名认证失败'
        })


def your_view(request):
    """
    渲染 data_import.html 页面，并传递 secret_key 到模板

    :param request: 请求对象
    :return: 渲染后的页面响应
    """
    secret_key = os.getenv('SECRET_KEY')
    context = {
        'secret_key': secret_key
    }
    return render(request, 'data_import.html', context)


def generate_uuid_token():
    """
    生成UUID令牌

    :return: 生成的UUID字符串
    """
    return str(uuid.uuid4())


def get_captcha(request):
    """
    生成验证码图片

    :param request: 请求对象
    :return: 验证码图片的响应
    """
    characters = string.ascii_letters + string.digits
    captcha = ''.join(random.choices(characters, k=4))
    request.session['captcha'] = captcha

    font = ImageFont.load_default()
    font_size = 32
    font = font.font_variant(size=font_size)

    img_width, img_height = 130, 40
    img = Image.new('RGB', (img_width, img_height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img)

    text_color = (random.randint(30, 100), random.randint(30, 100), random.randint(30, 100))
    x_start = 20
    for i, char in enumerate(captcha):
        x = x_start + i * 25
        y = (img_height - font_size) // 2
        draw.text((x, y), char, font=font, fill=text_color)

    for _ in range(5):
        x1 = random.randint(0, img_width)
        y1 = random.randint(0, img_height)
        x2 = random.randint(0, img_width)
        y2 = random.randint(0, img_height)
        draw.line((x1, y1, x2, y2), fill=(random.randint(150, 200), random.randint(150, 200), random.randint(150, 200)),
                  width=1)

    for _ in range(100):
        x = random.randint(0, img_width)
        y = random.randint(0, img_height)
        draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

    buffer = io.BytesIO()
    img.save(buffer, format='PNG')
    buffer.seek(0)

    response = HttpResponse(buffer, content_type='image/png')
    response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    return response


def register(request):
    """
    用户注册视图

    :param request: 请求对象
    :return: 渲染注册页面或重定向到登录页面
    """
    form = UserRegistrationForm(request.POST or None)
    if form.is_valid():
        form.save()
        messages.success(request, "注册成功，请登录")
        return redirect("login")
    return render(request, "register.html", {"form": form})


def login(request):
    """
    用户登录视图

    :param request: 请求对象
    :return: 渲染登录页面或重定向到主页面
    """
    if request.method == "POST":
        phone_number = request.POST.get('phone_number')
        password = request.POST.get('password')
        user = authenticate(request, username=phone_number, password=password)
        if user is not None:
            django_login(request, user)
            messages.success(request, "登录成功")
            return redirect("MainPage")
        else:
            messages.error(request, "电话号码或密码错误")
    return render(request, "login.html", {})


def logout(request):
    """
    用户注销视图

    :param request: 请求对象
    :return: 重定向到登录页面
    """
    django_logout(request)
    messages.success(request, "已成功注销")
    return redirect("login")


def MainPage(request):
    """
    主页面视图

    :param request: 请求对象
    :return: 渲染主页面
    """
    return render(request, "MainPage.html")


@login_required
def data_import(request):
    """
    数据导入视图

    :param request: 请求对象
    :return: 渲染数据导入页面或重定向到 Mydata 页面
    """
    if request.method == 'POST':
        form = DataUploadForm(request.POST, request.FILES)
        if form.is_valid():
            data_name = form.cleaned_data['data_name']
            data_description = form.cleaned_data['data_description']
            data_file = form.cleaned_data['data_file']
            phone_number = request.user.phone_number  # 从当前用户获取电话号码（更安全）

            # 计算签名和生成令牌
            file_content = data_file.read()
            signature = hashlib.sha256(file_content).hexdigest()
            token = str(uuid.uuid4())

            # 创建数据所有权记录并保存电话号码
            data_ownership = DataOwnership(
                owner=request.user,
                data_file=data_file,
                signature=signature,
                token=token,
                phone_number=phone_number,  # 关键：保存电话号码到模型
                # 以下字段根据你的模型实际字段调整（如果有的话）
                # data_name=data_name,
                # data_description=data_description,
            )
            data_ownership.save()

            messages.success(request, "数据上传成功")
            return redirect('Mydata')
        else:
            messages.error(request, "上传失败，请检查表单输入")
    else:
        # 初始化表单时自动填充电话号码（隐藏字段）
        initial_data = {'phone_number': request.user.phone_number}
        form = DataUploadForm(initial=initial_data)

    return render(request, 'data_import.html', {'form': form})


@login_required
def Mydata(request):
    """
    用户数据视图

    :param request: 请求对象
    :return: 渲染用户数据页面
    """
    owned_data = DataOwnership.objects.filter(owner=request.user)
    return render(request, 'Mydata.html', {'owned_data': owned_data})


def test_owner(request):
    """
    测试数据所有者视图

    :param request: 请求对象
    :return: 渲染测试所有者页面
    """
    token = request.GET.get('token')
    signature = request.GET.get('signature')
    return render(request, 'test_owner.html', {'token': token, 'signature': signature})


@login_required
def verify_token(request):
    """
    验证令牌视图

    :param request: 请求对象
    :return: 渲染授权页面或重定向到授权页面
    """
    if request.method == 'POST':
        form = TokenVerificationForm(request.POST)
        if form.is_valid():
            token = form.cleaned_data['token']
            try:
                auth_token = AuthorizationToken.objects.filter(new_token=token).first()
                if not auth_token:
                    messages.error(request, "无效的令牌")
                    return redirect('authorization_page')
                public_key_n = auth_token.public_key
                public_key = paillier.PaillierPublicKey(int(public_key_n))
                deserialize_encrypted_data(token, public_key)
                if auth_token.buyer_phone != request.user.phone_number:
                    messages.error(request, "您无权验证此令牌")
                    return redirect('authorization_page')

                token_data = generate_homomorphic_token()
                new_token = AuthorizationToken(
                    original_token=auth_token.new_token,
                    new_token=token_data['token'],
                    public_key=str(token_data['public_key']),
                    private_key=str(token_data['private_key']),
                    seller=request.user,
                    permission_percentage=auth_token.permission_percentage,
                    resale_level=auth_token.resale_level,
                    valid_days=auth_token.valid_days,
                    buyer_phone=None
                )
                new_token.save()

                messages.success(request, "令牌验证成功")
                return redirect('authorization_page')
            except Exception:
                messages.error(request, "无效的令牌")
    else:
        form = TokenVerificationForm()
    return render(request, 'authorization_page.html', {'form': form})


@login_required
def authorization_page(request):
    """
    授权页面视图

    :param request: 请求对象
    :return: 渲染授权页面
    """
    verify_form = TokenVerificationForm()
    token_param = request.GET.get('token')
    message = None

    if token_param:
        # 只允许认证过的数据生成新令牌
        data_obj = DataOwnership.objects.filter(token=token_param, owner=request.user).first()
        if data_obj:
            # 生成新同态加密令牌
            token_data = generate_homomorphic_token()
            new_token = AuthorizationToken.objects.create(
                original_token=token_param,
                new_token=token_data['token'],
                public_key=str(token_data['public_key']),
                private_key=str(token_data['private_key']),
                seller=request.user,
                permission_percentage=100,
                resale_level=3,
                valid_days=30,
                buyer_phone=None
            )
            message = "授权令牌生成成功，可进行转售。"
        else:
            message = "认证失败，您无权为此数据生成令牌。"

    if request.method == 'POST':
        if 'verify_token' in request.POST:
            return verify_token(request)
        form = TokenForm(request.POST, user=request.user)
        if form.is_valid():
            new_token = form.save()
            messages.success(request, "授权令牌生成成功")
            return redirect('authorization_page')
        else:
            messages.error(request, "授权令牌生成失败，请检查令牌是否属于您")
    else:
        form = TokenForm(user=request.user)

    tokens = AuthorizationToken.objects.filter(seller=request.user).order_by('-sale_time')
    return render(request, 'authorization_page.html', {
        'form': form,
        'verify_form': verify_form,
        'tokens': tokens,
        'message': message
    })


@login_required
def resale_token(request, token_id):
    """
    转售令牌视图

    :param request: 请求对象
    :param token_id: 令牌ID
    :return: 渲染转售令牌页面或重定向到授权页面
    """
    token_obj = get_object_or_404(AuthorizationToken, new_token=token_id)

    if request.user != token_obj.seller:
        messages.error(request, "您无权转售此令牌")
        return redirect('authorization_page')

    if request.method == 'POST':
        form = ResaleForm(request.POST)
        if form.is_valid():
            buyer_phone = form.cleaned_data['buyer_phone']
            new_resale_level = token_obj.resale_level - 1
            new_permission = max(20, token_obj.permission_percentage - 20)

            # 生成新的同态加密令牌
            token_data = generate_homomorphic_token()

            new_token = AuthorizationToken(
                original_token=token_obj.new_token,
                seller=request.user,
                new_token=token_data['token'],
                public_key=str(token_data['public_key']),
                private_key=str(token_data['private_key']),
                permission_percentage=new_permission,
                resale_level=new_resale_level,
                valid_days=form.cleaned_data['valid_days'],
                buyer_phone=buyer_phone
            )
            new_token.save()

            buyer = User.objects.filter(phone_number=buyer_phone).first()

            # 创建转售记录
            resale_record = ResaleRecord(
                authorization_token=token_obj,
                buyer_phone=buyer_phone,
                new_authorization_token=token_data['token'],
                public_key=str(token_data['public_key']),
                private_key=str(token_data['private_key']),
                resale_level=new_resale_level,
                valid_days=form.cleaned_data['valid_days'],
                permission_percentage=new_permission,
                buyer=buyer
            )
            resale_record.save()

            messages.success(request, f"转售成功（新令牌权限{new_permission}%，可转售级数{new_resale_level}）")
            return redirect('authorization_page')
    else:
        form = ResaleForm(initial={'valid_days': token_obj.valid_days})
    return render(request, 'resale_token.html', {'token': token_obj, 'form': form})


def resale_token_list(request):
    """
    转售令牌列表视图

    :param request: 请求对象
    :return: 渲染转售令牌列表页面
    """
    # 关联查询卖家的转售记录
    resale_records = ResaleRecord.objects.filter(authorization_token__seller=request.user).order_by('-resale_time')
    return render(request, 'resale_token_list.html', {'resale_records': resale_records})